﻿using System;
using System.Collections.Generic;
using System.Linq;
using Basmus.Values;
using Basmus.Values.Attributive;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Basmus.Tests.ContainerElements
{
    [TestClass]
    public class PropertyNameServiceTests
    {
        private IContextService _service;

        [TestInitialize]
        public void Initialize()
        {
            _service = new ContextService();
        }

        #region Test data

        public class Foo1
        {
            public int Prop1 { get; set; }

            public string SecondProp { get; set; }
        }

        public class Foo2
        {
            [Name("pr", "key2")]
            public int Prop2 { get; set; }

            public string SecondProp2 { get; set; }
        }

        public class Foo3
        {
            
            public int Prop3 { get; set; }

            [Name("second")]
            public string SecondProp3 { get; set; }
        }

        #endregion

        [TestMethod]
        public void GetSchemeKeys_NoAttributes_ReturnDefault()
        {
            //Arrange & Act
            var keys = _service.GetModelContexts(typeof(Foo1)).Select(x => x.SchemeKey);

            //Assert
            //For class without any library attributes GetSchemeKeys should return only default SchemeKey
            CollectionAssert.AreEqual(new[] { SchemeKey.Default }, keys.ToList());
        }

        [TestMethod]
        public void GetSchemeKeys_NameWithKeyAttribute_ReturnDefaultAndName()
        {
            //Arrange & Act
            var keys = _service.GetModelContexts(typeof(Foo2)).Select(x => x.SchemeKey);

            //Assert
            //For class having Name attribute with key specified GetSchemeKeys should return default SchemeKey and SchemeKey with corresponding name 
            var expected = new[] {SchemeKey.Default, SchemeKey.Create("key2")};
            CollectionAssert.AreEquivalent(expected, keys.ToList());
        }

        [TestMethod]
        public void GetSchemeKeys_NameWithoutKeyAttribute_ReturnDefault()
        {
            //Arrange & Act
            var keys = _service.GetModelContexts(typeof(Foo3)).Select(x => x.SchemeKey);

            //Assert
            //For class having Name attribute without key GetSchemeKeys should return only default SchemeKey
            CollectionAssert.AreEqual(new[] { SchemeKey.Default }, keys.ToList());
        }

        //[TestMethod]
        //public void GetProperties_NoAttributes_ReturnAllPropertyInfos()
        //{
        //    //Arrange & Act
        //    var props = _service.GetProperties(typeof(Foo1));

        //    //Assert
        //    var expected = new[] { new {PropertyType = typeof (int), Name = "Prop1"}, new { PropertyType = typeof(string), Name = "SecondProp" }};
        //    CollectionAssert.AreEqual(expected, props.Select(x => new {x.PropertyType, x.Name}).ToList(),
        //        "Regardless class attributes GetProperties should return all PropertyInfo-s");
        //}

        //[TestMethod]
        //public void GetProperties_NameWithKeyAttribute_ReturnAllPropertyInfos()
        //{
        //    //Arrange & Act
        //    var props = _service.GetProperties(typeof(Foo2));

        //    //Assert
        //    var expected = new[] { new { PropertyType = typeof(int), Name = "Prop2" }, new { PropertyType = typeof(string), Name = "SecondProp2" } };
        //    CollectionAssert.AreEqual(expected, props.Select(x => new { x.PropertyType, x.Name }).ToList(),
        //        "Regardless class attributes GetProperties should return all PropertyInfo-s");
        //}

        //[TestMethod]
        //public void GetProperties_NameWithoutKeyAttribute_ReturnAllPropertyInfos()
        //{
        //    //Arrange & Act
        //    var props = _service.GetProperties(typeof(Foo3));

        //    //Assert
        //    var expected = new[] { new { PropertyType = typeof(int), Name = "Prop3" }, new { PropertyType = typeof(string), Name = "SecondProp3" } };
        //    CollectionAssert.AreEqual(expected, props.Select(x => new { x.PropertyType, x.Name }).ToList(),
        //        "Regardless class attributes GetProperties should return all PropertyInfo-s");
        //}

        //#region GetName tests

        //[TestMethod]
        //public void GetNameTest1()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo1).GetProperty("Prop1"), null);

        //    //Assert
        //    Assert.AreEqual(name, "Prop1");
        //}

        //[TestMethod]
        //public void GetNameTest2()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo1).GetProperty("Prop1"), SchemeKey.Default);

        //    //Assert
        //    Assert.AreEqual(name, "Prop1");
        //}

        //[TestMethod]
        //public void GetNameTest3()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo1).GetProperty("Prop1"), SchemeKey.Create("someKey"));

        //    //Assert
        //    Assert.AreEqual(name, "Prop1");
        //}

        //[TestMethod]
        //public void GetNameTest4()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo2).GetProperty("Prop2"), null);

        //    //Assert
        //    Assert.AreEqual(name, "Prop2");
        //}

        //[TestMethod]
        //public void GetNameTest5()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo2).GetProperty("Prop2"), SchemeKey.Default);

        //    //Assert
        //    Assert.AreEqual(name, "Prop2");
        //}

        //[TestMethod]
        //public void GetNameTest6()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo2).GetProperty("Prop2"), SchemeKey.Create("key2"));

        //    //Assert
        //    Assert.AreEqual(name, "pr");
        //}

        //[TestMethod]
        //public void GetNameTest7()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo2).GetProperty("Prop2"), SchemeKey.Create("someKey"));

        //    //Assert
        //    Assert.AreEqual(name, "Prop2");
        //}

        //[TestMethod]
        //public void GetNameTest8()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo3).GetProperty("SecondProp3"), null);

        //    //Assert
        //    Assert.AreEqual(name, "second");
        //}

        //[TestMethod]
        //public void GetNameTest9()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo3).GetProperty("SecondProp3"), SchemeKey.Default);

        //    //Assert
        //    Assert.AreEqual(name, "second");
        //}

        //[TestMethod]
        //public void GetNameTest10()
        //{
        //    //Arrange & Act
        //    var name = _service.GetName(typeof(Foo3).GetProperty("SecondProp3"), SchemeKey.Create("someKey"));

        //    //Assert
        //    Assert.AreEqual(name, "second");
        //}

        //#endregion

        #region GetNames tests

        //[TestMethod]
        //public void GetNamesTest1()
        //{
        //    //Arrange & Act
        //    var names = _service.GetValueContexts(new ModelContext(typeof(Foo1), null));

        //    //Assert
        //    Assert.IsTrue(names.Any(x => x.Name == "Prop1"));
        //    Assert.IsTrue(names.Any(x => x.Name == "SecondProp"));
        //    Assert.IsTrue(names.Count() == 2);
        //}

        [TestMethod]
        public void GetNamesTest2()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo1), SchemeKey.Default));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop1"));
            Assert.IsTrue(names.Any(x => x.Name == "SecondProp"));
            Assert.IsTrue(names.Count() == 2);
        }

        [TestMethod]
        public void GetNamesTest3()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo1), SchemeKey.Create("someKey")));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop1"));
            Assert.IsTrue(names.Any(x => x.Name == "SecondProp"));
            Assert.IsTrue(names.Count() == 2);
        }

        //[TestMethod]
        //public void GetNamesTest4()
        //{
        //    //Arrange & Act
        //    var names = _service.GetValueContexts(new ModelContext(typeof(Foo2), null));

        //    //Assert
        //    Assert.IsTrue(names.Any(x => x.Name == "Prop2"));
        //    Assert.IsTrue(names.Any(x => x.Name == "SecondProp2"));
        //    Assert.IsTrue(names.Count() == 2);
        //}

        [TestMethod]
        public void GetNamesTest5()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo2), SchemeKey.Default));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop2"));
            Assert.IsTrue(names.Any(x => x.Name == "SecondProp2"));
            Assert.IsTrue(names.Count() == 2);
        }

        [TestMethod]
        public void GetNamesTest6()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo2), SchemeKey.Create("key2")));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "pr"));
            Assert.IsTrue(names.Any(x => x.Name == "SecondProp2"));
            Assert.IsTrue(names.Count() == 2);
        }

        [TestMethod]
        public void GetNamesTest7()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo2), SchemeKey.Create("someKey")));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop2"));
            Assert.IsTrue(names.Any(x => x.Name == "SecondProp2"));
            Assert.IsTrue(names.Count() == 2);
        }

        //[TestMethod]
        //public void GetNamesTest8()
        //{
        //    //Arrange & Act
        //    var names = _service.GetValueContexts(new ModelContext(typeof(Foo3), null));

        //    //Assert
        //    Assert.IsTrue(names.Any(x => x.Name == "Prop3"));
        //    Assert.IsTrue(names.Any(x => x.Name == "second"));
        //    Assert.IsTrue(names.Count() == 2);
        //}

        [TestMethod]
        public void GetNamesTest9()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo3), SchemeKey.Default));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop3"));
            Assert.IsTrue(names.Any(x => x.Name == "second"));
            Assert.IsTrue(names.Count() == 2);
        }

        [TestMethod]
        public void GetNamesTest10()
        {
            //Arrange & Act
            var names = _service.GetValuesContexts(new ModelContext(typeof(Foo3), SchemeKey.Create("someKey")));

            //Assert
            Assert.IsTrue(names.Any(x => x.Name == "Prop3"));
            Assert.IsTrue(names.Any(x => x.Name == "second"));
            Assert.IsTrue(names.Count() == 2);
        }

        #endregion

        //#region GetPropertyInfoNames tests

        //[TestMethod]
        //public void GetPropertyInfoNamesTest1()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo1), null));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop1" && x.Item1.Name == "Prop1"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp" && x.Item1.Name == "SecondProp"));            
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest2()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo1), SchemeKey.Default));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop1" && x.Item1.Name == "Prop1"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp" && x.Item1.Name == "SecondProp"));
            
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest3()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo1), SchemeKey.Create("someKey")));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop1" && x.Item1.Name == "Prop1"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp" && x.Item1.Name == "SecondProp"));

        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest4()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo2), null));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop2" && x.Item1.Name == "Prop2"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp2" && x.Item1.Name == "SecondProp2"));
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest5()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo2), SchemeKey.Default));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop2" && x.Item1.Name == "Prop2"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp2" && x.Item1.Name == "SecondProp2"));

        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest6()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo2), SchemeKey.Create("key2")));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "pr"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "pr" && x.Item1.Name == "Prop2"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp2" && x.Item1.Name == "SecondProp2"));
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest7()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo2), SchemeKey.Default));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop2" && x.Item1.Name == "Prop2"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "SecondProp2" && x.Item1.Name == "SecondProp2"));
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest8()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo3), null));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop3" && x.Item1.Name == "Prop3"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "second" && x.Item1.Name == "SecondProp3"));
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest9()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo3), null));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop3" && x.Item1.Name == "Prop3"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "second" && x.Item1.Name == "SecondProp3"));
        //}

        //[TestMethod]
        //public void GetPropertyInfoNamesTest10()
        //{
        //    //Arrange
        //    var infos = _service.GetPropertyInfoNames(new ModelContext(typeof(Foo3), null));

        //    //Act & Assert
        //    Assert.IsNotNull(infos);
        //    Assert.IsTrue(infos.Count() == 2);
        //    Assert.IsTrue(infos.All(x => x != null));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "Prop3" && x.Item1.Name == "Prop3"));
        //    Assert.IsTrue(infos.Any(x => x.Item2 == "second" && x.Item1.Name == "SecondProp3"));
        //}

        //#endregion

        //#region Build tests

        //[TestMethod]
        //public void GetPropertyInfoTest1()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo1), null, "Prop1");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop1");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), null, "SecondProp");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), null, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest2()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo1), SchemeKey.Default, "Prop1");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop1");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), SchemeKey.Default, "SecondProp");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), SchemeKey.Default, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest3()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo1), SchemeKey.Create("someKey"), "Prop1");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop1");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), SchemeKey.Create("someKey"), "SecondProp");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo1), SchemeKey.Create("someKey"), "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest4()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo2), null, "Prop2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop2");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), null, "pr");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), null, "SecondProp2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp2");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), null, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest5()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo2), SchemeKey.Default, "Prop2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop2");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), null, "pr");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Default, "SecondProp2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp2");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Default, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest6()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo2), SchemeKey.Create("someKey"), "Prop2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop2");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), null, "pr");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Create("someKey"), "SecondProp2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp2");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Create("someKey"), "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest7()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo2), SchemeKey.Create("key2"), "Prop2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop2");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Create("key2"), "pr");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop2");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Create("key2"), "SecondProp2");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp2");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo2), SchemeKey.Create("key2"), "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest8()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo3), null, "Prop3");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop3");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), null, "SecondProp3");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), null, "second");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp3");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), null, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest9()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo3), SchemeKey.Default, "Prop3");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop3");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Default, "SecondProp3");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Default, "second");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp3");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Default, "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}

        //[TestMethod]
        //public void GetPropertyInfoTest10()
        //{
        //    //Arrange
        //    var prop = _service.Build(typeof(Foo3), SchemeKey.Create("someKey"), "Prop3");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "Prop3");
        //    Assert.AreEqual(prop.PropertyType, typeof(int));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Create("someKey"), "SecondProp3");

        //    //Act & Assert
        //    Assert.IsNull(prop);

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Create("someKey"), "second");

        //    //Act & Assert
        //    Assert.IsNotNull(prop);
        //    Assert.AreEqual(prop.Name, "SecondProp3");
        //    Assert.AreEqual(prop.PropertyType, typeof(string));

        //    //Arrange
        //    prop = _service.Build(typeof(Foo3), SchemeKey.Create("someKey"), "wrongProp");

        //    //Act & Assert
        //    Assert.IsNull(prop);
        //}


        //#endregion

        [TestMethod]
        public void GettingKeysTest()
        {
            //Arrange
            var keys = _service.GetModelContexts(typeof(Foo1)).Select(x => x.SchemeKey);

            //Act & Assert
            Assert.IsNotNull(keys);
            Assert.IsTrue(keys.Count() == 1);
            Assert.IsTrue(keys.First().IsDefault);
            Assert.IsTrue(keys.First().Key == SchemeKey.Default.Key);
            Assert.AreEqual(keys.First(), SchemeKey.Default);

            //Arrange
            keys = _service.GetModelContexts(typeof(Foo2)).Select(x => x.SchemeKey);
            var schemeKey = SchemeKey.Create("key2");

            //Act & Assert
            Assert.IsNotNull(keys);
            Assert.IsTrue(keys.Count() == 2);
            Assert.IsTrue(keys.Any(k => k == SchemeKey.Default));
            var key = keys.First(k => k != SchemeKey.Default);
            Assert.AreEqual(key, schemeKey);
            Assert.IsTrue(key == schemeKey);
            Assert.IsTrue(key.Equals(schemeKey));
        }

        [TestMethod]
        public void SchemeKeyTest()
        {
            //Arrange
            var defaultKey = SchemeKey.Default;
            var key1 = SchemeKey.Create("key1");
            var key11 = SchemeKey.Create("key1");
            var key2 = SchemeKey.Create("Key2");

            //Assert
            Assert.AreNotEqual(key1, defaultKey);
            Assert.AreNotEqual(defaultKey, key1);
            Assert.AreNotEqual(key1, key2);
            Assert.AreNotEqual(key2, key1);
            Assert.AreEqual(key1, key11);
            Assert.AreEqual(key11, key1);
        }
    }
}
